package com.task.core.service.impl;


import com.task.core.service.DataNoticeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Service
public class DataNoticeServiceImpl implements DataNoticeService {

    private static final Map<String,SseEmitter> sseEmitterMap = new ConcurrentHashMap<>();

    @Override
    public SseEmitter crateSse(String uid) {
        SseEmitter sseEmitter = new SseEmitter(0L);
        sseEmitter.onCompletion(() -> {
            log.info("[{}]结束链接" , uid);
            sseEmitterMap.remove(uid);
        });
        sseEmitter.onTimeout(() -> {
            log.info("[{}]链接超时",uid);
        });
        sseEmitter.onError(throwable -> {
            try{
                log.info("[{}]链接异常，{}",uid,throwable.toString());
                sseEmitter.send(SseEmitter.event()
                        .id(uid)
                        .name("发生异常")
                        .data("发生异常请重试")
                        .reconnectTime(3000));
                sseEmitterMap.put(uid,sseEmitter);
            }catch (IOException e){
                e.printStackTrace();
            }
        });
        try{
            sseEmitter.send(SseEmitter.event().reconnectTime(5000));
        }catch (IOException e){
            e.printStackTrace();
        }
        sseEmitterMap.put(uid,sseEmitter);
        log.info("[{}]创建sse连接成功!",uid);
        return sseEmitter;
    }

    @Override
    public boolean sendMessage(String uid,String message){
        if (StringUtils.isEmpty(message)) {
            log.info("[{}]参数异常，msg为空", uid);
            return false;
        }
        SseEmitter sseEmitter = sseEmitterMap.get(uid);
        if (sseEmitter == null) {
            log.info("[{}]sse连接不存在", uid);
            return false;
        }
        try {
            sseEmitter.send(SseEmitter.event().reconnectTime(60000).data(message));
            log.info("数据{}, 推送成功：{}", uid, message);
            return true;
        } catch (IOException e) {
            sseEmitterMap.remove(uid);
            log.info("数据{}, 消息推送失败：{}", uid, message);
            sseEmitter.complete();
            return false;
        }
    }

    @Override
    public void closeSse(String uid){
        if(sseEmitterMap.containsKey(uid)){
            SseEmitter sseEmitter = sseEmitterMap.get(uid);
            sseEmitter.complete();
            sseEmitterMap.remove(uid);
        }else {
            log.info("数据{}连接已关闭",uid);
        }
    }

}

